<!--
 * @Author: xiaxia
 * @Description: 
 * @Date: 2023-07-05 13:48:57
 * @LastEditTime: 2023-12-20 15:00:07
 * @FilePath: \pdf-print\src\App.vue
-->
<template>
  <div clas="app">
    <div>
      <h2>pdf打印</h2>
      <el-form label-width="85px"  size="mini">
        <el-form-item label="打印机">
          <el-select
            v-model="dyParam.printer"
            placeholder="请选择"
          >
            <el-option
              v-for="item in locaolPrinter"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <el-button type="primary" @click="getLocalPrint()">获取本地打印机</el-button>
      <el-button type="primary" @click="printPdf(dyParam, true)">直接打印</el-button>
      <el-button type="primary" @click="printPdf(dyParam, false)">打印预览</el-button>
    </div>
  </div>
</template>

<script>
  import { getFileBase64, getLocalPrint } from './utils/printjs.js'
  import {getLodop} from './utils/LodopFuncs' // clodop
  import * as pdfjsLib from "pdfjs-dist"
  const pdfjsWorker = import("pdfjs-dist/build/pdf.worker.entry")
  pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker

  export default {
    name: 'App',
    data(){
      return{
        // dyParam 包含打印的配置信息：发票号码 打印机，打印份数等...
        dyParam: {
          goldtaxNum: '', // 发票号码
          printer: '', // 打印机名称
          dyNumber: 1, // 打印份数
        },
        locaolPrinter: null, // 获取到的本地打印机
      }
    },
    methods:{
      async printPdf(dyParam, ispreview) {
        let answer = null
        let fpNum = dyParam.goldtaxNum// 这里去获取发票号码
        let LODOP = getLodop() // 初始化clodop 没有控件会提示用户安装
        
        // 1. pdf地址
        // 这里使用pdf地址 可根据自己项目替换
        const url = "http://localhost:8000/CLodopDemos/PDFDemo.pdf"
        const zhUrl = await getFileBase64(url) // 模拟请求，获得blob类型地址
        const loadingTask = pdfjsLib.getDocument(zhUrl)
        console.log('pdf地址111111:', zhUrl)

        // 2. 文件流
        // let strURL = dyParam.row.file.address // pdf地址
        // let res = await getPrintFeil({FileAddress: strURL}) // 请求后端 获取文件流
        // let bolbFile = new Blob([res.data], { type: 'application/pdf; charset=utf-8' })
        // let blobUrl =  getObjectURL(bolbFile)
        // const loadingTask = pdfjsLib.getDocument(blobUrl)
        // console.log( 'pdf地址111111:' , blobUrl);

        let pdf = null
        try {
          pdf= await loadingTask.promise
        } catch(e) {
          return answer = { success: false,msg: "未查询到pdf地址,请联系管理员" }
        }
        let numPages = pdf.numPages
        // 1. 如果当前打印的页数 <= 10 ------------------------------------------------------------------
        if(numPages <= 10) {
          LODOP.PRINT_INIT('发票'+fpNum)
          LODOP.SET_PRINT_PAGESIZE(1, 2200, 2970, "") // 设置纸张大小A4 纵向打印
          // LODOP.SET_PRINT_PAGESIZE(2, 0, 0, "A4") // 设置纸张大小A4 横向打印
          for(let i=1; i<=numPages; i++){
            await this.CreateOnePage( LODOP, pdf, i)
          }

          if(ispreview) { // 判断是预览还是直接打印
            LODOP.SET_PRINTER_INDEX(dyParam.printer)
            LODOP.PRINT() // 打印
          } else {
            LODOP.PREVIEW() // 预览
          }
          this.$message.success('发票 '+ dyParam.goldtaxNum +' 解析完成正在发送请求到打印机,请耐心等待......');

          return new Promise((resolve) => {
            LODOP.On_Return = function (TaskID, Value) {
              if(Value){
                console.log('打印成功：发送打印请求成功')
                answer = { success: true, msg: "发送打印请求成功" }
              } else {
                console.log('打印失败：发送打印请求失败')
                answer = { success: false, msg: "发送打印请求失败" }
              }
              resolve(answer) // 完成Promise
            }
          })
        }
        // 2. 当前页数>10--需要进行分组 ------------------------------------------------------------------
        else {
          let num1 = Math.ceil(numPages/10) // 向上取整
          for (let it = 0; it <= num1-1; it++) {
            LODOP.PRINT_INIT('发票'+fpNum)
            LODOP.SET_PRINT_PAGESIZE(1, 2200, 2970, ""); // 设置纸张大小
            // LODOP.SET_PRINT_PAGESIZE(2, 0, 0, "A4"); // 设置纸张大小A4 横向打印
            if(it == 0) {
              for (let ind = 1; ind <= 10; ind++) {
                await this.CreateOnePage( LODOP, pdf, ind)
              }
            } else{
              for (let ind = 1; ind <= 10; ind++) {
                if(ind == 10){
                  await this.CreateOnePage(LODOP, pdf, parseInt(it+1+''+0))
                  if(parseInt(it+1+''+0)==numPages) break
                } else {
                  await this.CreateOnePage( LODOP, pdf, parseInt(it+''+ind))
                  if(parseInt(it+''+ind)==numPages) break
                }
              }
            }
            LODOP.SET_PRINT_MODE("CUSTOM_TASK_NAME",'发票'+fpNum+'第'+(it+1)+'份') // 单独任务名
            console.log('当前打印的页数>10,打印份数：', this.dyNumber)
            LODOP.SET_PRINT_COPIES(this.dyNumber) // 打印份数

            if(ispreview) { // 判断是预览还是直接打印
              LODOP.SET_PRINTER_INDEX(dyParam.printer)
              LODOP.PRINT() // 打印
            } else {
              LODOP.PREVIEW() // 预览
            }
          }
          this.$message.success(' 解析完成正在发送请求到打印机,请耐心等待......');
          return new Promise((resolve) => {
            LODOP.On_Return = function (TaskID, Value) {
              if(Value){
                console.log('打印成功：发送打印请求成功')
                answer = { success: true, msg: "发送打印请求成功" }
              } else {
                console.log('发送打印请求失败')
                answer = { success: false, msg: "发送打印请求失败" }
              }
              resolve(answer); // 完成Promise
            }
          })
        }
      },
      // pdf解析
      async CreateOnePage(LODOP, pdf, i){
        LODOP.NewPage()
        let pdfId = "pdf" + i
        const newCanvas = document.createElement("canvas") // 新建画布
        newCanvas.setAttribute("id", pdfId) // 赋id
        const page = await pdf.getPage(i)
        const context = newCanvas.getContext("2d")
        const viewport = page.getViewport({ scale: 7}) // scale值越大越清晰 解析时间越长
        newCanvas.height = viewport.height
        newCanvas.width = viewport.width
        const renderContext = {
          canvasContext: context,
          viewport: viewport,
        };
        await page.render(renderContext).promise
        console.log("Page rendered")
        const img = newCanvas.toDataURL("image/jpeg") // 转换成image地址

        LODOP.ADD_PRINT_IMAGE(0, 0, "95%", "95%", img)
        LODOP.SET_PRINT_STYLEA(0,"Stretch",2)
        newCanvas.remove() // 销毁画布
      },
      getLocalPrint() {
        this.locaolPrinter = getLocalPrint()
        console.log(this.locaolPrinter);
      }
    }
  }
</script>

<style>
.app {
  text-align: center;
}
canvas {
  border: 1px solid #ccc;
}
img {
  width: 600px;
  height: 500px;
  border: 1px solid red;
}
.content {
  display: flex;
  align-items: center;
  justify-content: center;
}
.pdf {
  margin-right: 20px;
}
</style>
